/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_zml.htm
 *
 * Zhiqim Zml is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.zml;

import java.io.StringWriter;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.extend.MapS;
import org.zhiqim.kernel.extend.HashMapSO;
import org.zhiqim.kernel.extend.MapSO;

/**
 * ZhiqimML工具类
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
@AnAlias("Zmls")
public class Zmls implements SignConstants
{
    /******************************************************************/
    //指定内容，把ZML标签转义为浏览器可读标签
    /******************************************************************/
    
    /**
     * 内容格式化，对<,>,\",\',${,@{,#{格式化，保证浏览器解释成字符串而不是ZML代码
     * 
     * @param content   要格式化的字符串
     * @return          格式化后的字符串
     */
    public static String format(String content)
    {
        if (content == null)
            return "";
        
        StringBuilder strb = new StringBuilder();
        for (int i=0;i<content.length();i++)
        {
            char c = content.charAt(i);
            switch (c)
            {
            //检查HTML/ZML非表达式语句标签，进行转化
            case '<':strb.append("&lt;");break;
            case '>':strb.append("&gt;");break;
            case '\'':strb.append("&apos;");break;
            case '\"':strb.append("&quot;");break;
            case '{':
            {//检查ZML表达式语句标签，进行转化
                if (i == 0)
                    strb.append(c);
                else
                {
                    switch (content.charAt(i-1))
                    {
                    case '$':strb.setLength(strb.length()-1);strb.append("&#x24;{");break;
                    case '@':strb.setLength(strb.length()-1);strb.append("&#x40;{");break;
                    case '#':strb.setLength(strb.length()-1);strb.append("&#x23;{");break;
                    default:strb.append(c);break;
                    }
                }
                break;
            }
            default:strb.append(c);break;
            }
        }
        
        return strb.toString();
    }
    
    /******************************************************************/
    //指定内容，解释内容生成结果
    /******************************************************************/
    
    /**
     * 解析ZML内容和属性表得到解析之后的内容
     * 
     * @param content       指定ZML的内容
     * @param key           变量KEY
     * @param value         变量VALUE
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(String content, String key, Object value) throws Exception
    {
        return parse(new Zml(content), key, value);
    }
    
    /**
     * 解析ZML内容和属性表得到解析之后的内容
     * 
     * @param content       指定ZML的内容
     * @param variableMap   页变量表
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(String content, MapSO variableMap, MapS... contextMap) throws Exception
    {
        return parse(new Zml(content), variableMap, contextMap);
    }
    
    /**
     * 解析ZML内容和属性表得到解析之后的内容
     * 
     * @param content       指定ZML的内容
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parseContext(String content, MapS... contextMap) throws Exception
    {
        return parseContext(new Zml(content), contextMap);
    }
    
    /******************************************************************/
    //指定ZML，解释ZML生成结果
    /******************************************************************/
    
    /**
     * 解析ZML和属性表得到解析之后的内容
     * 
     * @param zml           ZML对象
     * @param key           变量KEY
     * @param value         变量VALUE
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(Zml zml, String key, Object value) throws Exception
    {
        return parse(zml, new HashMapSO(key, value));
    }
    
    /**
     * 解析ZML和属性表得到解析之后的内容
     * 
     * @param zml           ZML对象
     * @param variableMap   页变量表
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(Zml zml, MapSO variableMap, MapS... contextMap) throws Exception
    {
        StringWriter writer = new StringWriter();
        zml.process(writer, variableMap, contextMap);
        
        return writer.toString();
    }
    
    /**
     * 解析ZML和属性表得到解析之后的内容
     * 
     * @param zml           ZML对象
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parseContext(Zml zml, MapS... contextMap) throws Exception
    {
        StringWriter writer = new StringWriter();
        zml.process(writer, null, contextMap);
        
        return writer.toString();
    }
}
